package cn.px.service.store.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.px.common.bean.AbstractPageResultBean;
import cn.px.common.enums.DataFilterTypeEnum;
import cn.px.common.exception.BusinessException;
import cn.px.common.model.UserInfo;
import cn.px.common.util.BeanConverterUtil;
import cn.px.common.util.IdGeneratorUtils;
import cn.px.common.util.SecurityUtils;
import cn.px.dao.bean.MyPage;
import com.github.pagehelper.PageHelper;
import cn.px.dao.dto.store.StoreDTO;
import cn.px.dao.dto.upms.SysDeptDTO;
import cn.px.dao.entity.store.SpareStore;
import cn.px.dao.entity.store.Store;
import cn.px.dao.entity.upms.SysDept;
import cn.px.dao.entity.upms.SysUserDept;
import cn.px.dao.enums.DelFlagEnum;
import cn.px.dao.enums.DeptNatureEnum;
import cn.px.dao.enums.StoreLevelEnum;
import cn.px.dao.mapper.store.SpareStoreMapper;
import cn.px.dao.mapper.upms.SysDeptMapper;
import cn.px.dao.util.CustomExcelImportUtil;
import cn.px.dao.util.UserUtil;
import cn.px.dao.vo.query.store.StoreVO;
import cn.px.dao.vo.query.upms.SysDeptVO;
import cn.px.service.store.StoreService;
import cn.px.service.upms.SysDeptService;
import cn.px.service.upms.SysUserDeptService;
import cn.px.service.util.ExecuteSql;
import org.springframework.stereotype.Service;
import cn.px.service.base.impl.BaseServiceImpl;
import cn.px.dao.mapper.store.StoreMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;
import lombok.AllArgsConstructor;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description 仓库信息 service 实现类
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2020,北京乾元坤和科技有限公司 All rights reserved.
 */
@AllArgsConstructor
@Service("storeService")
public class StoreServiceImpl extends BaseServiceImpl<StoreMapper, Store, StoreDTO> implements StoreService {

    private SysUserDeptService sysUserDeptService;
    private SysDeptService sysDeptService;
    private SysDeptMapper deptMapper;
    private SpareStoreMapper spareStoreMapper;
    private StoreMapper storeMapper;
    private final String useArea = "5e64ac691c527828b2114da0";
    private final String useCompany = "6063f905eb190003685af6d4";
    private final String useProject = "6063f92ceb190003685af6d9";

    @Override
    public int batchDelete(List<String> ids) {
        Weekend<Store> weekend = new Weekend<>(Store.class);
        WeekendCriteria<Store, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andIn(Store::getId, ids);
        mapper.deleteByExample(weekend);

        // 删除仓库备件数据
        Weekend<SpareStore> weekendSpareStore = new Weekend<>(SpareStore.class);
        WeekendCriteria<SpareStore, Object> weekendCriteriaSpareStore = weekendSpareStore.weekendCriteria();
        weekendCriteriaSpareStore.andIn(SpareStore::getStoreId, ids);
        spareStoreMapper.deleteByExample(weekendSpareStore);
        return 1;
    }

    /**
     * 可选择全部，也可以选择登录用户对应的仓库
     *
     * @param record
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public AbstractPageResultBean<StoreVO> selectPageList(StoreDTO record, int pageNum, int pageSize) {

        if(record.getUseCompany() !=null || record.getUseProject() !=null ){
            record.setFilter(null);
        }
        // 登录人自己负责的项目列表
        if (record.getFilter() != null && DataFilterTypeEnum.SELF.getValue() == record.getFilter().intValue()) {
            UserInfo userInfo = SecurityUtils.getUserInfo();
            record.setUserId(userInfo.getUserId());
        }

        // 项目部的仓库列表
        if (record.getFilter() != null && DataFilterTypeEnum.PROJECT.getValue() == record.getFilter().intValue()) {
            UserInfo userInfo = SecurityUtils.getUserInfo();
            List<SysUserDept> sysUserDepts = sysUserDeptService.selectByUserId(userInfo.getUserId());
            if (CollectionUtil.isEmpty(sysUserDepts)) {
                throw new BusinessException("找不到该用户所属部门，请先设置，用户id:" + userInfo.getUserId());
            }
            SysDeptDTO sysDeptDTO = new SysDeptDTO();
            sysDeptDTO.setDescendant(sysUserDepts.get(0).getDeptId());
            sysDeptDTO.setNature(DeptNatureEnum.XIANG_MU_BU.getValue());
            List<SysDeptVO> list = sysDeptService.allParentList(sysDeptDTO);
            if (CollectionUtil.isEmpty(list)) {
                throw new BusinessException("找不到该用户所属的项目组，请先设置，用户id:" + userInfo.getUserId());
            }
            record.setUseProject(list.get(0).getDeptId());
        }
        if (record.getFilter() != null && DataFilterTypeEnum.COMPANY.getValue() == record.getFilter().intValue()) {
            UserInfo userInfo = SecurityUtils.getUserInfo();
            List<SysUserDept> sysUserDepts = sysUserDeptService.selectByUserId(userInfo.getUserId());
            if (CollectionUtil.isEmpty(sysUserDepts)) {
                throw new BusinessException("找不到该用户所属部门，请先设置，用户id:" + userInfo.getUserId());
            }
            SysDeptDTO sysDeptDTO = new SysDeptDTO();
            sysDeptDTO.setDescendant(sysUserDepts.get(0).getDeptId());
            sysDeptDTO.setNature(DeptNatureEnum.FEN_GONG_SI.getValue());
            List<SysDeptVO> list = sysDeptService.allParentList(sysDeptDTO);
            if (CollectionUtil.isEmpty(list)) {
                throw new BusinessException("找不到该用户所属的公司，请先设置，用户id:" + userInfo.getUserId());
            }
            record.setUseCompany(list.get(0).getDeptId());
        }

        PageHelper.startPage(pageNum, pageSize);
        return new MyPage(mapper.selectList(record));
    }

    /**
     * 获取登录用户所属项目部下面某种类型的仓库
     * 如果type为空，则选择全部仓库
     *
     * @param storeDTO
     * @return
     */
    @Override
    public AbstractPageResultBean<StoreVO> getModelListByLoginUserDept(StoreDTO storeDTO, int pageNum, int pageSize) {
        UserInfo userInfo = SecurityUtils.getUserInfo();
        SysDeptVO userNatureDept = UserUtil.getUserNatureDept(DeptNatureEnum.XIANG_MU_BU, userInfo);
        storeDTO.setUseProject(userNatureDept.getDeptId());
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage<>(mapper.selectList(storeDTO));
    }

    @Override
    public List<StoreVO> selectListByUserId(String userId) {
        return mapper.selectList(new StoreDTO().setUserId(userId));
    }

    @Override
    public List<StoreVO> selectListByProjectId(String projectId) {
        return mapper.selectList(new StoreDTO().setUseProject(projectId));
    }

    /**
     * 查找某个项目部的总仓
     *
     * @param projectId ：
     * @param level     ：
     * @return
     */
    @Override
    public StoreVO selectOneByProjectIdAndType(String projectId, Integer level) {
        List<StoreVO> storeList = mapper.selectList(new StoreDTO().setUseProject(projectId).setType(StoreLevelEnum.ZONGCANG.getValue()));
        if (CollectionUtils.isEmpty(storeList)) {
            throw new BusinessException("未设置总仓，请先设置");
        }
        if (storeList.get(0).getUserId() == null) {
            throw new BusinessException("找不到该项目部对应的总仓的负责人，请设置负责人,仓库id：" + storeList.get(0).getId());
        }
        return storeList.get(0);
    }

    @Override
    public List<StoreVO> selectListByCompanyId(String companyId) {
        return mapper.selectList(new StoreDTO().setUseCompany(companyId));
    }

    @Override
    public AbstractPageResultBean<Store> selectPageInfo(StoreDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage(mapper.selectList(record));
    }

    @Override
    public Store saveModelByDTO(StoreDTO model) {
        Weekend<Store> weekend = new Weekend<>(Store.class);
        weekend.weekendCriteria().andIsNotNull(Store::getId);
        Integer count = mapper.selectCountByExample(weekend);
        model.setNo(IdGeneratorUtils.getStoreNo(++count));
       /* if (StoreLevelEnum.ZONGCANG.getValue().equals(model.getLevel())) {
            Store search = new Store();
            search.setLevel(model.getLevel());
            search.setUseCompany(model.getUseCompany());
            search.setUseProject(model.getUseProject());
            List<Store> list = mapper.select(search);
            if(!CollectionUtils.isEmpty(list)){
                throw new BusinessException("该项目部已经存在总仓，总仓只能有一个，请调整");
            }
        }*/
        model.setUseCompany(useCompany);
        model.setUseProject(useProject);
        return super.saveModelByDTO(model);
    }

    @Override
    public void modModelByDTO(StoreDTO model) {

       /* if (StoreLevelEnum.ZONGCANG.getValue().equals(model.getLevel())) {
            Store search = new Store();
            search.setLevel(model.getLevel());
            search.setUseCompany(model.getUseCompany());
            search.setUseProject(model.getUseProject());
            Store ss = mapper.selectOne(search);
            if (ss != null && StoreLevelEnum.ZONGCANG.getValue().equals(ss.getLevel()) && !ss.getId().equals(model.getId())) {
                throw new BusinessException("该项目部已经存在总仓，总仓只能有一个");
            }
        }*/
        super.modModelByDTO(model);
    }

    @Override
    public List<Store> getModelListByDTO(StoreDTO model) {
        Weekend<Store> weekend = new Weekend(Store.class);
        WeekendCriteria<Store, Object> weekendCriteria = weekend.weekendCriteria();
        ExecuteSql.executeNotEmpty(model.getId(), () -> weekendCriteria.andNotEqualTo(Store::getId, model.getId()));
        ExecuteSql.executeNotEmpty(model.getUseProject(), () -> weekendCriteria.andEqualTo(Store::getUseProject, model.getUseProject()));
        ExecuteSql.executeNotNull(model.getLevel(), () -> weekendCriteria.andEqualTo(Store::getLevel, model.getLevel()));

        // 登录人自己负责的仓库列表
        if (model.getFilter() != null && DataFilterTypeEnum.SELF.getValue() == model.getFilter().intValue()) {
            UserInfo userInfo = SecurityUtils.getUserInfo();
            weekendCriteria.andEqualTo(Store::getUserId, userInfo.getUserId());
        }
        // 项目部的仓库列表
        if (model.getFilter() != null && DataFilterTypeEnum.PROJECT.getValue() == model.getFilter().intValue()) {
            UserInfo userInfo = SecurityUtils.getUserInfo();
            List<SysUserDept> sysUserDepts = sysUserDeptService.selectByUserId(userInfo.getUserId());
            if (CollectionUtil.isEmpty(sysUserDepts)) {
                throw new BusinessException("找不到该用户所属部门，请先设置，用户id:" + userInfo.getUserId());
            }
            SysDeptDTO sysDeptDTO = new SysDeptDTO();
            sysDeptDTO.setDescendant(sysUserDepts.get(0).getDeptId());
            sysDeptDTO.setNature(DeptNatureEnum.XIANG_MU_BU.getValue());
            List<SysDeptVO> list = sysDeptService.allParentList(sysDeptDTO);
            if (CollectionUtil.isEmpty(list)) {
                throw new BusinessException("找不到该用户所属的项目组，请先设置，用户id:" + userInfo.getUserId());
            }
            weekendCriteria.andEqualTo(Store::getUseProject, list.get(0).getDeptId());
        }
        if (model.getFilter() != null && DataFilterTypeEnum.COMPANY.getValue() == model.getFilter().intValue()) {
            UserInfo userInfo = SecurityUtils.getUserInfo();
            List<SysUserDept> sysUserDepts = sysUserDeptService.selectByUserId(userInfo.getUserId());
            if (CollectionUtil.isEmpty(sysUserDepts)) {
                throw new BusinessException("找不到该用户所属部门，请先设置，用户id:" + userInfo.getUserId());
            }
            SysDeptDTO sysDeptDTO = new SysDeptDTO();
            sysDeptDTO.setDescendant(sysUserDepts.get(0).getDeptId());
            sysDeptDTO.setNature(DeptNatureEnum.FEN_GONG_SI.getValue());
            List<SysDeptVO> list = sysDeptService.allParentList(sysDeptDTO);
            if (CollectionUtil.isEmpty(list)) {
                throw new BusinessException("找不到该用户所属的公司，请先设置，用户id:" + userInfo.getUserId());
            }
            weekendCriteria.andEqualTo(Store::getUseCompany, list.get(0).getDeptId());
        }
        return mapper.selectByExample(weekend);
    }

    private void setWeekendCriteria(Weekend<Store> weekend, StoreDTO model) {
        WeekendCriteria<Store, Object> weekendCriteria = weekend.weekendCriteria();
        ExecuteSql.executeNotEmpty(model.getId(), () -> weekendCriteria.andNotEqualTo(Store::getId, model.getId()));
        ExecuteSql.executeNotEmpty(model.getUseProject(), () -> weekendCriteria.andEqualTo(Store::getUseProject, model.getUseProject()));
        ExecuteSql.executeNotNull(model.getLevel(), () -> weekendCriteria.andEqualTo(Store::getLevel, model.getLevel()));
    }

    @Override
    public Store getById(String id) {
        Store store = mapper.selectByPrimaryKey(id);
        if(store == null){
            throw new BusinessException("找不到仓库信息，storeID:" + store.getId());
        }
        List<String> deptIdList = new ArrayList<String>();
        deptIdList.add(store.getUseCompany());
        deptIdList.add(store.getUseProject());
        int num = deptIdList.size();
        Weekend<SysDept> weekend3 = new Weekend<>(SysDept.class);
        weekend3.weekendCriteria().andIn(SysDept::getDeptId, deptIdList);
        List<SysDept> deptList = deptMapper.selectByExample(weekend3);
        deptList.forEach(sysDept -> {
            if(sysDept.getDeptId().equals(store.getUseCompany())){
                store.setUseCompanyName(sysDept.getName());
            }
            if(sysDept.getDeptId().equals(store.getUseProject())){
                store.setUseProjectName(sysDept.getName());
            }
        });
        return store;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importListAddAndUpdate(String storeId, MultipartFile file) {
        //UserInfo userInfo = SecurityUtils.getUserInfo();
        int addNum = 0;
        int updateNum = 0;
        try {
            List<SpareStore> items = CustomExcelImportUtil.importSpareStoreList(file.getInputStream());
            if(!CollectionUtils.isEmpty(items)){
                spareStoreMapper.updateBatch(items);
            }
            return "已更新："+ items.size()+ ", 总计："+ (items.size());
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
    }

    /**
     * 将某个仓库的备件库存全部转移到另外的仓库
     * 原仓库库存全部为0，原仓库为0的不迁移
     * 新仓库已存在的备件直接增加数量或者新增备件
     *
     * @param sourceStoreId
     * @param destStoreId
     * @return
     */
    @Override
    public String changeStore(String sourceStoreId, String destStoreId) {
        Weekend<SpareStore> weekend = new Weekend<>(SpareStore.class);
        WeekendCriteria<SpareStore, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andEqualTo(SpareStore::getStoreId, sourceStoreId);
        List<SpareStore> storeList = spareStoreMapper.selectByExample(weekend);
        Weekend<SpareStore> weekend2 = new Weekend<>(SpareStore.class);
        WeekendCriteria<SpareStore, Object> weekendCriteria2 = weekend2.weekendCriteria();
        weekendCriteria2.andEqualTo(SpareStore::getStoreId, destStoreId);
        List<SpareStore> destStoreList = spareStoreMapper.selectByExample(weekend2);
        List<SpareStore> addList = new ArrayList<SpareStore>();
        List<SpareStore> updateList = new ArrayList<SpareStore>();
        String result = "";
        int notChange = 0;
        if(CollectionUtil.isNotEmpty(storeList)){
            if(CollectionUtil.isNotEmpty(destStoreList)){
                for(SpareStore source:storeList){
                    // 原仓库为0的不迁移
                    if(source.getNum()!=null && source.getNum().compareTo(new BigDecimal(0))==0){
                        notChange++;
                        continue;
                    }
                    boolean find = false;
                    for(SpareStore dest:destStoreList){
                        if(source.getSpareId().equals(dest.getSpareId())){
                            find = true;
                            dest.setNum(dest.getNum().add(source.getNum()));
                            updateList.add(dest);
                            break;
                        }
                    }
                    if(!find){
                        SpareStore create = BeanConverterUtil.copyObjectProperties(source, SpareStore.class);
                        create.setId(IdGeneratorUtils.getObjectId());
                        create.setStoreId(destStoreId);
                        addList.add(create);
                    }
                }

                for(SpareStore source:storeList){
                    source.setNum(new BigDecimal(0));
                }
                Store sourceStore = storeMapper.selectByPrimaryKey(sourceStoreId);
                sourceStore.setDelFlag(DelFlagEnum.DELETED.getValue());

                // 更新旧仓库
                spareStoreMapper.updateBatchByStoreChange(storeList);
                storeMapper.updateByPrimaryKey(sourceStore);

                // 更新新仓库
                if(CollectionUtil.isNotEmpty(addList)){
                    spareStoreMapper.insertListforComplex(addList);
                }

                if(CollectionUtil.isNotEmpty(updateList)){
                    spareStoreMapper.updateBatchByStoreChange(updateList);
                }
                result = "总迁移备件条数：" + storeList.size() + "迁移更新数量:" + updateList.size()+ "迁移新增数量："
                        + addList.size()+ "未迁移新增数量（为0的备件不迁移）：" +notChange;
            }
        }
        return result;
    }
}
